/**
 * 任务相关方法
 *
 * @format
 */

import UserService from './user.service'
import {
  getToday,
  getUserOrderlist,
  generateVipUrl,
  formatVipCbUrl,
  setNewFollowUserData,
  setNewVipUserData
} from '../../utils'
import { STAT_TYPE, TASK_RATE_TYPE, TASK_STATUS } from '../../constants'
import { getTodayCompleteTask, getTotalCompleteTask, setTaskStatus } from '../../utils/common/task'
import { CODE_TYPES } from '../../errorCode'
import { BaseDao } from '../../sdk'
import { STAT_DB_NAME } from '../../db'

export interface ITaskInfo {
  taskType?: string // 任务类型
  url?: string // 链接地址
  reward: number // 任务奖励
  itemIds?: string // 商品配置ids 商品相关任务返回
  todayCompleteTimes?: number // 今日完成次数
  completeTimes?: number // 总共完成次数
  rateType: number // 任务频率
  times?: number // 任务每日限制次数
  waitReceive?: number // 待领取次数
  title: string // 任务文案
  status: number // 任务状态 1未完成 2 待领取 3 已完成
}
export default class TaskService extends UserService {
  statdao: IBaseDao
  constructor(context: IContext<IParams>) {
    super(context)
    this.statdao = new BaseDao(context, STAT_DB_NAME)
  }

  // 根据活动tasks字段渲染任务
  async initTaskList(userInfo: IUserInfo, activityInfo: IActivityInfo) {
    return {
      list: Object.keys(activityInfo?.tasks || {}).map((task: ITaskType) => {
        return this.initTask(task, activityInfo?.tasks?.[task]?.title, userInfo, activityInfo)
      })
    }
  }
  /**
   *  根据任务类型初始化   b端 tasks字段必须有相应的配置TODO
   *
   * @param {ITaskType} taskType 任务类型
   * @param {string} title 任务标题
   * @param {IActivityInfo} activityInfo 任务配置
   * @param {IUserInfo} userInfo 用户信息
   * @return {ITaskInfo}  {ITaskInfo} 任务信息
   * @memberof TaskService
   */
  initTask(taskType: ITaskType, title: string, userInfo: IUserInfo, activityInfo: IActivityInfo): Object {
    if (!activityInfo?.tasks?.[taskType]) {
      console.error(`活动缺少${taskType}任务配置项`)
    }
    const { reward, itemIds = '', rateType, times = 1, link = '' } = activityInfo?.tasks?.[taskType] || {}
    const { remainTimes } = userInfo
    const { todayCompleteTimes } = getTodayCompleteTask(taskType, userInfo)
    const { completeTimes } = getTotalCompleteTask(taskType, userInfo)

    return {
      key: taskType,
      type: taskType,
      title,
      itemIds,
      reward,
      rateType,
      times,
      url: taskType === 'member' ? generateVipUrl(formatVipCbUrl(this.context)) : link,
      todayCompleteTimes,
      completeTimes: rateType === TASK_RATE_TYPE.EVERYDAY ? todayCompleteTimes : completeTimes,
      status: setTaskStatus(userInfo, taskType, rateType, times),
      waitReceive: remainTimes?.[taskType]
    }
  }

  /**
   *
   * 领取任务奖励
   *
   * @param {ITaskType} taskType
   * @param {string} awardsTargetKey
   * @param {IUserInfo} userInfo
   * @return {number} rewards
   * @memberof TaskService
   */
  async receiveTaskRewards(
    taskType: ITaskType,
    awardsTargetKey: string,
    userInfo: IUserInfo
  ): Promise<{
    rewards: number
  }> {
    const waitReceiveTimes = userInfo?.remainTimes?.[taskType]

    // await this.updateUser(userInfo._id, {
    //   $set: {
    //     [`remainTimes.${taskType}`]: 0
    //   },
    //   $inc: {
    //     [awardsTargetKey]: waitReceiveTimes
    //   }
    // })

    return {
      rewards: waitReceiveTimes
    }
  }

  /**
   *根据任务类型更新任务待领取次数和任务记录
   *
   * @param {string} taskType
   * @param {number} activityInfo
   * @param {IActivityInfo} userInfo
   * @returns {boolean}
   * @memberof TaskService
   */
  async completeTask(
    taskType: ITaskType,
    activityInfo: IActivityInfo,
    userInfo: IUserInfo,
    customRecord: Object = {}
  ): Promise<Object> {
    const today = getToday()
    const reward = activityInfo?.tasks?.[taskType]?.reward || 0
    let {
      openId,
      data: { itemId, inviteId, isVip }
    } = this.context

    // 邀请任务由被邀请人完成，单独处理
    if (taskType === 'invite') {
      if (!inviteId) return CODE_TYPES.ERROR_INVALID_INVITE_ID
      if (openId === inviteId) return CODE_TYPES.ERROR_NO_INVITE_SELF
      // if (userInfo?.inviteId) return CODE_TYPES.ERROR_AREADY_INVITE_SUCCESS
      // 是否是新会员助力
      // if (!isVip) return CODE_TYPES.ERROR_NO_VIP
      // const isNewVip = !userInfo?.member?.flag && isVip
      // if (!isNewVip) return CODE_TYPES.ERROR_INVITE

      const {
        _id,
        tasks: { invite }
      } = activityInfo
      // 获取邀请者信息
      const inviteUserInfo = await this.userdao.findOne<IUserInfo>({
        activityId: _id,
        openId: inviteId
      })
      // inviteId的用户信息查询不到, 则inviteId无效
      if (!inviteUserInfo) return CODE_TYPES.ERROR_INVALID_INVITE_ID

      // if (inviteUserInfo.taskInfo?.[`${getToday()}`]?.invite?.find(itm => itm.openId === userInfo.openId)) {
      //   return CODE_TYPES.ERROR_TODAY_AREADY_INVITE_SUCCESS
      // }

      // const todayHelpCount = await this.statdao.count({ createDay: getToday(), openId })

      // if (todayHelpCount > 2) {
      //   return CODE_TYPES.ERROR_HELP_TIMES_LIMIT
      // }

      const { rateType = 2, times = 5 } = invite
      const { todayCompleteTimes } = getTodayCompleteTask('invite', inviteUserInfo)
      // 助力次数超限制
      if (rateType === TASK_RATE_TYPE.EVERYDAY && todayCompleteTimes >= times) {
        return CODE_TYPES.ERROR_INVITE_TIMES_LIMIT
      }
      openId = inviteId
      userInfo = inviteUserInfo
    }

    // 完成任务
    const record = { itemId, openId: taskType === 'invite' ? openId : undefined, ...customRecord }
    let updateQuery: IUpdateQuery = {
      $inc: {
        [`remainTimes.${taskType}`]: +reward
      },
      $push: {
        [`taskInfo.${today}.${taskType}`]: { ...record, createTime: Date.now() }
      }
    }
    if (taskType === 'follow') {
      updateQuery.$set = {
        follow: setNewFollowUserData(userInfo.follow)
      }
    }
    if (taskType === 'member') {
      updateQuery.$set = {
        member: setNewVipUserData(userInfo.member)
      }
    }
    // const result = await this.updateUser(userInfo._id, updateQuery)

    return  { ok: 1 } 
  }

  async getItemListWithCollectStatus(list: { list: ITaoBaoItems[] }, userInfo: IUserInfo) {
    const { taskInfo } = getTotalCompleteTask('collectGoods', userInfo)

    return {
      list: list.list.map(v => {
        return {
          ...v,
          // 完成列表是否含有itemId
          collected: taskInfo.some(completeItem => completeItem.itemId === v.itemId)
        }
      })
    }
  }
}
